def modify_class_attrs(parent, modifier):
    class ChildBase(parent.__metaclass__):
        def __new__(cls, name, bases, attrs):
            return super(ChildBase, cls).__new__(cls, name, bases, modifier(attrs))
    class Child(parent):
        __metaclass__ = ChildBase
    return Child

def cache_method_value(func):
    name = '_cache_%s' % func.__name__
    def decorated(self, *args, **kwargs):
        if not hasattr(self, name):
            setattr(self, name, func(self, *args, **kwargs))
        return getattr(self, name)
    return decorated

def update_object_attrs(obj, **attrs):
    for k in attrs:
        if not hasattr(obj, k):
            setattr(obj, k, attrs[k])

def merge_attrs(*objects):
    class Res(object):
        def __getattr__(self, name):
            for obj in objects:
                try:
                    return getattr(obj, name)
                except AttributeError:
                    continue
            raise AttributeError, 'Unknown attribute `%s`' % name
    return Res()

def copy_attrs(src, dest, attrs=()):
    for name in attrs:
        try:
            setattr(dest, name, getattr(src, name))
        except AttributeError:
            pass

def copy_func_attrs(src, dest, attrs=('__doc__',
                                      '__dict__',
                                      '__name__',
                                      '__module__')
):
    copy_attrs(src, dest, attrs)
